package com.fr.report.script;

import com.fr.base.ColumnRow;
import com.fr.base.FRContext;
import com.fr.base.Inter;
import com.fr.base.StringUtils;
import com.fr.base.core.antlr.ANTLRException;
import com.fr.data.impl.RowsTableData;
import com.fr.report.Report;
import com.fr.report.TableDataSource;
import com.fr.report.core.FormReport;
import com.fr.report.core.FormReport.Action;
import com.fr.report.core.ParameterHelper;
import com.fr.report.core.SegmentHandler;
import com.fr.report.core.SegmentHandler.QueryCreator;
import com.fr.report.script.core.parser.Ambiguity;
import com.fr.report.script.core.parser.CRAddress;
import com.fr.report.script.core.parser.ColumnRowLiteral;
import com.fr.report.script.core.parser.ColumnRowRange;
import com.fr.report.script.core.parser.Expression;
import com.fr.report.script.core.parser.FRLexer;
import com.fr.report.script.core.parser.FRParser;
import com.fr.report.script.core.parser.Tiny;
import com.fr.report.script.core.parser.TinyHunter;
import com.fr.report.script.core.parser.UtilEvalError;
import com.fr.util.Utils;
import java.io.Serializable;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class Calculator
  implements Serializable, Cloneable
{
  private CNS globalNameSpace = new CNS();
  private Map parsedExpression = new HashMap();
  private Map attributes = new HashMap();
  private static final Object REPORT = new Object();
  private static final Object TABLEDATA = new Object();
  private static final Object COLUMNROW = new Object();
  private static final Object CUR_ROWSTABLEDATA = new Object();
  private static Hashtable calculators = new Hashtable();
  private static final Pattern deprecatedParaPattern = Pattern.compile("\\[\\?[^\\]\\?]*\\?\\]");
  public static Pattern ParameterPattern = Pattern.compile("\\$\\{((\\\"[^(\\$\\{)]*\\}[^(\\$\\{)]*\\\")|(\\\"[^(\\$\\{)]*[^\\$]?\\{[^(\\$\\{)]*\\\")|[^\\{\\}])*+\\}");

  public static Calculator currentCalculator()
  {
    return ((Calculator)calculators.get(Thread.currentThread()));
  }

  public static Calculator createCalculator()
  {
    return new Calculator();
  }

  public static Calculator createStaticCalculator()
  {
    Calculator localCalculator = new Calculator();
    calculators.put(Thread.currentThread(), localCalculator);
    return localCalculator;
  }

  public void release()
  {
    calculators.remove(Thread.currentThread());
  }

  public void setCurrentReport(Report paramReport)
  {
    this.attributes.put(REPORT, paramReport);
  }

  public Report getCurrentReport()
  {
    return ((Report)this.attributes.get(REPORT));
  }

  public void setCurrentTableDataSource(TableDataSource paramTableDataSource)
  {
    this.attributes.put(TABLEDATA, paramTableDataSource);
  }

  public TableDataSource getCurrentTableDataSource()
  {
    return ((TableDataSource)this.attributes.get(TABLEDATA));
  }

  public void setCurrentColumnRow(ColumnRow paramColumnRow)
  {
    this.attributes.put(COLUMNROW, paramColumnRow);
  }

  public RowsTableData getCurrentRowsTableData()
  {
    return ((RowsTableData)this.attributes.get(CUR_ROWSTABLEDATA));
  }

  public void setCurrentRowsTableData(RowsTableData paramRowsTableData)
  {
    this.attributes.put(CUR_ROWSTABLEDATA, paramRowsTableData);
  }

  public ColumnRow getCurrentColumnRow()
  {
    return ((ColumnRow)this.attributes.get(COLUMNROW));
  }

  public void setAttribute(Object paramObject1, Object paramObject2)
  {
    this.attributes.put(paramObject1, paramObject2);
  }

  public Object getAttribute(Object paramObject)
  {
    return this.attributes.get(paramObject);
  }

  public void set(String paramString, Object paramObject)
  {
    CNS.access$000(this.globalNameSpace, paramString, paramObject);
  }

  public void pushNameSpace(NameSpace paramNameSpace)
  {
    CNS.access$100(this.globalNameSpace).addFirst(paramNameSpace);
  }

  public boolean removeNameSpace(NameSpace paramNameSpace)
  {
    return CNS.access$100(this.globalNameSpace).remove(paramNameSpace);
  }

  public Object resolveVariable(Object paramObject)
  {
    return this.globalNameSpace.getVariable(paramObject, this);
  }

  public Function resolveMethod(Object paramObject)
  {
    return this.globalNameSpace.getMethod(paramObject, this);
  }

  public Object resolveCellElementAttribute(ColumnRow paramColumnRow, Object paramObject)
  {
    return this.globalNameSpace.getCellElementAttribute(paramColumnRow, paramObject, this);
  }

  public Expression parse(Object paramObject)
    throws ANTLRException
  {
    if (paramObject instanceof Expression)
      return ((Expression)paramObject);
    return parse(Utils.objectToString(paramObject));
  }

  public Expression parse(String paramString)
    throws ANTLRException
  {
    if (paramString == null)
      return null;
    paramString = paramString.trim();
    if (paramString.startsWith("="))
      paramString = paramString.substring(1);
    Expression localExpression = (Expression)this.parsedExpression.get(paramString);
    if (localExpression == null)
    {
      StringReader localStringReader = new StringReader(paramString);
      FRLexer localFRLexer = new FRLexer(localStringReader);
      FRParser localFRParser = new FRParser(localFRLexer);
      localExpression = localFRParser.parse();
      this.parsedExpression.put(paramString, localExpression);
    }
    return localExpression;
  }

  public Object eval(String paramString)
    throws UtilEvalError
  {
    Expression localExpression = null;
    if (paramString != null)
      try
      {
        localExpression = parse(paramString);
      }
      catch (ANTLRException localANTLRException)
      {
        if (getCurrentColumnRow() != null)
        {
          StringBuffer localStringBuffer = new StringBuffer().append(Inter.getLocText("Error_Cell") + ":").append(getCurrentColumnRow()).append(Inter.getLocText("Error_Statement_Is") + "\"").append(paramString).append('"').append('\n').append(localANTLRException.getMessage());
          FRContext.getLogger().log(Level.WARNING, localStringBuffer.toString(), localANTLRException);
        }
        else
        {
          FRContext.getLogger().log(Level.WARNING, Inter.getLocText("Error_Statement_Is") + "\"" + paramString + "\"", localANTLRException);
        }
      }
    return ((localExpression == null) ? null : localExpression.eval(this));
  }

  public static ColumnRow[] relatedColumnRowArray(String paramString)
    throws ANTLRException
  {
    Expression localExpression = new Calculator().parse(paramString);
    if (localExpression == null)
      return new ColumnRow[0];
    ColumnRowHunter localColumnRowHunter = new ColumnRowHunter(null);
    localExpression.traversal4Tiny(localColumnRowHunter);
    return localColumnRowHunter.getColumnRowBooty();
  }

  public static String[] relatedParameters(String paramString)
    throws ANTLRException
  {
    Expression localExpression = new Calculator().parse(paramString);
    if (localExpression == null)
      return new String[0];
    ParameterHunter localParameterHunter = new ParameterHunter(null);
    localExpression.traversal4Tiny(localParameterHunter);
    return localParameterHunter.getParameterBooty();
  }

  public String exStatement(ColumnRow paramColumnRow, String paramString)
  {
    setCurrentColumnRow(paramColumnRow);
    Expression localExpression = null;
    try
    {
      localExpression = parse(paramString);
    }
    catch (ANTLRException localANTLRException)
    {
      if (getCurrentColumnRow() != null)
      {
        StringBuffer localStringBuffer = new StringBuffer().append("Error Cell: ").append(getCurrentColumnRow()).append(" and statement is \"").append(paramString).append('"').append('\n').append(localANTLRException.getMessage());
        FRContext.getLogger().log(Level.WARNING, localStringBuffer.toString(), localANTLRException);
      }
      else
      {
        FRContext.getLogger().log(Level.WARNING, "error statement is \"" + paramString + "\"", localANTLRException);
      }
    }
    return ((localExpression == null) ? paramString : localExpression.exString(this));
  }

  public String onAddDeleteColumnOrRow(String paramString, int paramInt1, int paramInt2, int paramInt3, int paramInt4)
  {
    Expression localExpression = null;
    try
    {
      localExpression = parse(paramString);
    }
    catch (ANTLRException localANTLRException)
    {
      if (getCurrentColumnRow() != null)
      {
        StringBuffer localStringBuffer = new StringBuffer().append("Error Cell: ").append(getCurrentColumnRow()).append(" and statement is \"").append(paramString).append('"').append('\n').append(localANTLRException.getMessage());
        FRContext.getLogger().log(Level.WARNING, localStringBuffer.toString(), localANTLRException);
      }
      else
      {
        FRContext.getLogger().log(Level.WARNING, "error statement is \"" + paramString + "\"", localANTLRException);
      }
    }
    return ((localExpression == null) ? paramString : localExpression.getExpression(paramInt1, paramInt2, paramInt3, paramInt4, true));
  }

  public void extract(ColumnRow[] paramArrayOfColumnRow, ColumnRow paramColumnRow, FormReport.Action paramAction)
    throws Exception
  {
    int i = 0;
    Report localReport = getCurrentReport();
    if (localReport instanceof FormReport)
      i = ((FormReport)localReport).setCurrentColumnRow(paramArrayOfColumnRow, paramColumnRow, this, paramAction);
    if (i <= 0)
      paramAction.run(0, this);
  }

  public String renderTpl(String paramString)
  {
    if (deprecatedParaPattern.matcher(paramString).find())
    {
      localObject1 = new SegmentHandler.QueryCreator(this);
      ParameterHelper.analyzeParametersFromQuery(paramString, (SegmentHandler)localObject1);
      return ((SegmentHandler.QueryCreator)localObject1).getNewQuery();
    }
    Object localObject1 = ParameterPattern.matcher(paramString);
    StringBuffer localStringBuffer = new StringBuffer();
    int i = 0;
    int j = 0;
    while (true)
    {
      Object localObject2;
      do
      {
        if (!(((Matcher)localObject1).find()))
          break label145;
        j = ((Matcher)localObject1).start();
        String str1 = paramString.substring(i, j);
        i = ((Matcher)localObject1).end();
        localStringBuffer.append(str1);
        String str2 = ((Matcher)localObject1).group();
        String str3 = str2.substring(2, str2.length() - 1);
        localObject2 = null;
        try
        {
          localObject2 = eval(str3);
        }
        catch (UtilEvalError localUtilEvalError)
        {
        }
      }
      while (localObject2 == null);
      localStringBuffer.append(Utils.objectToString(localObject2));
    }
    label145: localStringBuffer.append(paramString.substring(i));
    return ((String)localStringBuffer.toString());
  }

  protected static class CNS extends AbstractNameSpace
  {
    private Map variables = new HashMap();
    private LinkedList namespaceList = new LinkedList();

    public Function getMethod(Object paramObject, Calculator paramCalculator)
    {
      Function localFunction = null;
      int i = 0;
      int j = this.namespaceList.size();
      while (i < j)
      {
        localFunction = ((NameSpace)this.namespaceList.get(i)).getMethod(paramObject, paramCalculator);
        if (localFunction != null)
          return localFunction;
        ++i;
      }
      return super.getMethod(paramObject, paramCalculator);
    }

    public Object getCellElementAttribute(ColumnRow paramColumnRow, Object paramObject, Calculator paramCalculator)
    {
      Object localObject = null;
      int i = 0;
      int j = this.namespaceList.size();
      while (i < j)
      {
        localObject = ((NameSpace)this.namespaceList.get(i)).getCellElementAttribute(paramColumnRow, paramObject, paramCalculator);
        if (localObject != null)
          return localObject;
        ++i;
      }
      return localObject;
    }

    public Object getVariable(Object paramObject, Calculator paramCalculator)
    {
      Object localObject = null;
      localObject = unwrapVariable((Variable)this.variables.get(paramObject));
      if (localObject != null)
        return localObject;
      int i = 0;
      int j = this.namespaceList.size();
      while (i < j)
      {
        localObject = ((NameSpace)this.namespaceList.get(i)).getVariable(paramObject, paramCalculator);
        if (localObject != null)
          return localObject;
        ++i;
      }
      return super.getVariable(paramObject, paramCalculator);
    }

    private Object unwrapVariable(Variable paramVariable)
    {
      return ((paramVariable == null) ? null : paramVariable.getValue());
    }

    private void set(Object paramObject1, Object paramObject2)
    {
      if (paramObject1 == null)
        return;
      if (paramObject2 == null)
        paramObject2 = Primitive.NULL;
      Variable localVariable = (Variable)this.variables.get(paramObject1);
      if (localVariable != null)
        localVariable.setValue(paramObject2);
      else
        this.variables.put(paramObject1, new Variable(paramObject2));
    }

    static void access$000(CNS paramCNS, Object paramObject1, Object paramObject2)
    {
      paramCNS.set(paramObject1, paramObject2);
    }

    static LinkedList access$100(CNS paramCNS)
    {
      return paramCNS.namespaceList;
    }
  }

  private static class ParameterHunter extends TinyHunter
  {
    private List parameterList;

    private ParameterHunter()
    {
      this.parameterList = new ArrayList();
    }

    public String[] getParameterBooty()
    {
      return ((String[])this.parameterList.toArray(new String[this.parameterList.size()]));
    }

    public void hunter4Tiny(Tiny paramTiny)
    {
      if (paramTiny instanceof Ambiguity)
      {
        String str = ((Ambiguity)paramTiny).getStatement();
        if ((StringUtils.isNotBlank(str)) && (str.startsWith("$")) && (!(this.parameterList.contains(str))))
          this.parameterList.add(str);
      }
    }

    ParameterHunter(Calculator.1 param1)
    {
    }
  }

  private static class ColumnRowHunter extends TinyHunter
  {
    private List list;

    private ColumnRowHunter()
    {
      this.list = new ArrayList();
    }

    public ColumnRow[] getColumnRowBooty()
    {
      return ((ColumnRow[])this.list.toArray(new ColumnRow[this.list.size()]));
    }

    public void hunter4Tiny(Tiny paramTiny)
    {
      Object localObject;
      if (paramTiny instanceof ColumnRowRange)
      {
        localObject = (ColumnRowRange)paramTiny;
        ColumnRowLiteral localColumnRowLiteral1 = ((ColumnRowRange)localObject).getFrom();
        if (localColumnRowLiteral1 == null)
          return;
        ColumnRow localColumnRow1 = localColumnRowLiteral1.getTargetColumnRow();
        ColumnRow localColumnRow2 = localColumnRow1;
        ColumnRowLiteral localColumnRowLiteral2 = ((ColumnRowRange)localObject).getTo();
        if (localColumnRowLiteral2 != null)
          localColumnRow2 = localColumnRowLiteral2.getTargetColumnRow();
        int i = Math.min(localColumnRow1.column, localColumnRow2.column);
        int j = Math.min(localColumnRow1.row, localColumnRow2.row);
        int k = Math.max(localColumnRow1.column, localColumnRow2.column);
        int l = Math.max(localColumnRow1.row, localColumnRow2.row);
        int i1 = i;
        while (true)
        {
          if (i1 > k)
            return;
          for (int i2 = j; i2 <= l; ++i2)
          {
            ColumnRow localColumnRow3 = ColumnRow.valueOf(i1, i2);
            if ((!(this.list.contains(localColumnRow3))) && (ColumnRow.validate(localColumnRow3)))
              this.list.add(localColumnRow3);
          }
          ++i1;
        }
      }
      if (paramTiny instanceof CRAddress)
      {
        localObject = ((CRAddress)paramTiny).getTarget();
        if ((!(this.list.contains(localObject))) && (ColumnRow.validate((ColumnRow)localObject)))
          this.list.add(localObject);
      }
    }

    ColumnRowHunter(Calculator.1 param1)
    {
    }
  }
}